package com.lagou.edu.message.server;

import java.net.SocketAddress;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;

import com.alibaba.fastjson.JSON;
import com.corundumstudio.socketio.*;
import org.apache.commons.lang.StringUtils;

import com.corundumstudio.socketio.listener.ConnectListener;
import com.corundumstudio.socketio.listener.DataListener;
import com.corundumstudio.socketio.listener.DisconnectListener;
import com.corundumstudio.socketio.listener.ExceptionListener;
import com.corundumstudio.socketio.namespace.Namespace;
import com.corundumstudio.socketio.protocol.Packet;
import com.corundumstudio.socketio.protocol.PacketType;
import com.corundumstudio.socketio.store.pubsub.DispatchMessage;
import com.lagou.edu.common.jwt.JwtUtil.JwtResult;
import com.lagou.edu.common.string.GsonUtil;
import com.lagou.edu.message.api.dto.Message;
import com.lagou.edu.message.consts.Constants;
import com.lagou.edu.message.server.dicpacth.Dispatcher;
import com.lagou.edu.message.server.store.StoreFacotryProvider;
import com.lagou.edu.message.util.PushUtils;
import com.lagou.edu.message.util.ServerConfigUtils;

import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import lombok.extern.slf4j.Slf4j;

@Slf4j
public class PushServer {

    public static final PushServer pushServer = new PushServer();

    private static List<SocketIOClient> clients = new ArrayList<>();

    private Namespace pushNamespace;

    private final SocketIOServer server;

    private PushServer() {
        Configuration config = new Configuration();
        config.setOrigin(ServerConfigUtils.instance.getWebSocketOrigin());
        config.setPort(ServerConfigUtils.instance.getWebSocketPort());
        String context = ServerConfigUtils.instance.getWebSocketContext();
//        config.setContext(context);
        server = new SocketIOServer(config);
//        pushNamespace = (Namespace) server.addNamespace(context);
        server.addConnectListener(new ConnectListener() {
            @Override
            public void onConnect(SocketIOClient client) {
                clients.add(client);
            }
        });

        server.addDisconnectListener(new DisconnectListener() {
            @Override
            public void onDisconnect(SocketIOClient client) {
                clients.remove(client);
            }
        });
    }

    /**
     * 推送消息
     *
     * @param message
     */
    public void push(Message message) {
        String json = JSON.toJSONString(message);
        Packet packet = new Packet(PacketType.MESSAGE);
//        packet.setName("message");
        packet.setData(json);
        for (SocketIOClient client: clients) {
//            System.out.println(client.getRemoteAddress()+"*************");
//            System.out.println(client.getTransport().getValue()+"*************");
            client.sendEvent("message", packet);
        }
    }

    /**
     * 同步启动服务；
     */
    public void start() {
        try {
            server.start();
        } catch (Exception e) {
            log.error("Push server start failed!", e);
            System.exit(-1);
        }
    }

    /**
     * 停止服务
     */
    public void stop() {
        server.stop();
    }

    public Map<String, Object> getStatus() {
        HashMap<String, Object> status = new HashMap<>();
        status.put("namespace", pushNamespace.getName());   // namespace
        status.put("rooms", pushNamespace.getRooms());
        status.put("clients", pushNamespace.getAllClients().size());
        return status;
    }

}
